﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Siser.Web.Models;
using Siser.Web.Models.JsonResponses;

namespace Siser.Web.Shared
{
    public static class Math
    {
        public static decimal Integral(List<Medicion> mediciones)
        {
            int r = 0;
            string[] tempo1 = new string[mediciones.Count];
            DateTime[] fechas = new DateTime[mediciones.Count];
            float[] valores_med = new float[mediciones.Count];

            foreach (Medicion medicion in mediciones)
            {
                valores_med[r] = (float)medicion.Valor;
                fechas[r] = medicion.Fecha;
                r++;
            }

            decimal[] dif_t = new decimal[mediciones.Count];
            for (int i = 0; i < fechas.Length - 1; i++)
            {
                TimeSpan diferencia = fechas[i + 1].Subtract(fechas[i]);
                dif_t[i] = Convert.ToDecimal(diferencia.TotalHours.ToString("#.00000000000"));
            }

            decimal resultado = 00000000000000.000000000000000000000M;
            for (int i = 0; i < valores_med.Length - 1; i++)
            {
                if (valores_med[i] < valores_med[i + 1] || valores_med[i] == valores_med[i + 1])
                {
                    decimal a = (decimal)(valores_med[i]);
                    decimal b = (dif_t[i]);
                    decimal c = (decimal)(System.Math.Abs(valores_med[i + 1] - valores_med[i]));

                    resultado += (a * b) + (0.5M * (c) * (b));
                }
                else
                {
                    decimal a = (decimal)(valores_med[i + 1]);
                    decimal b = (dif_t[i]);
                    decimal c = (decimal)(System.Math.Abs(valores_med[i + 1] - valores_med[i]));
                    resultado += (a * b) + (0.5M * (c) * (b));
                }
            }

            return resultado;
        }

        public static decimal Average(List<Medicion> mediciones)
        {
            decimal valor_suma = 0.000M;
            int n = 0;
            foreach (Medicion medicion in mediciones)
            {
                valor_suma += (decimal)medicion.Valor;
                n++;
            }

            return valor_suma / n;
        }

        public static decimal Variance(List<Medicion> mediciones)
        {
            decimal valor_cuadrado = 0.000M;
            int n = 0;
            foreach (Medicion medicion in mediciones)
            {
                valor_cuadrado += (decimal)System.Math.Pow(((double)medicion.Valor - (double)Average(mediciones)), 2);
                n++;
            }
            return valor_cuadrado / n;
        }

        public static decimal StandardDeviation(List<Medicion> mediciones)
        {
            return (decimal)System.Math.Sqrt((double)Variance(mediciones));
        }

        public static float Maximum(List<Medicion> mediciones)
        {
            return mediciones.Max(m => m.Valor);
        }

        public static float Minium(List<Medicion> mediciones)
        {
            return mediciones.Min(m => m.Valor);
        }
    }
}